home *** CD-ROM | disk | FTP | other *** search
/ PC-SIG: World of Games / PC-SIG World of Games (CDRM1080710) (1993).iso / ENT / DISK2468.ZIP / MM / MOUSE.C < prev    next >
Text File  |  1990-05-04  |  15KB  |  503 lines

  1. /********************************************************************
  2.  *        Mouse toolkit            (mouse.c)
  3.  ********************************************************************/
  4. #include <bios.h>
  5. #include <dos.h>
  6. #include <conio.h>
  7. #include <process.h>
  8. #include <stdio.h>
  9. #include "\tc\myincs\mouse.h"
  10.  
  11. /* Mouse cursor shapes are defined */
  12. unsigned int standard_curs[16][2];
  13. unsigned int up_arrow_curs[16][2];
  14.  
  15. /* standard cursor shape : screen mask array */
  16. /* standard_curs[ 0][0] = 0x3fff;    0011111111111111 */
  17. /* standard_curs[ 1][0] = 0x1fff;    0001111111111111 */
  18. /* standard_curs[ 2][0] = 0x0fff;    0000111111111111 */
  19. /* standard_curs[ 3][0] = 0x07ff;    0000011111111111 */
  20. /* standard_curs[ 4][0] = 0x03ff;    0000001111111111 */
  21. /* standard_curs[ 5][0] = 0x01ff;    0000000111111111 */
  22. /* standard_curs[ 6][0] = 0x00ff;    0000000011111111 */
  23. /* standard_curs[ 7][0] = 0x007f;    0000000001111111 */
  24. /* standard_curs[ 8][0] = 0x003f;    0000000000111111 */
  25. /* standard_curs[ 9][0] = 0x001f;    0000000000011111 */
  26. /* standard_curs[10][0] = 0x01ff;    0000000000001111 */
  27. /* standard_curs[11][0] = 0x10ff;    0001000011111111 */
  28. /* standard_curs[12][0] = 0x30ff;    0011000011111111 */
  29. /* standard_curs[13][0] = 0xf87f;    1111100001111111 */
  30. /* standard_curs[14][0] = 0xf87f;    1111100001111111 */
  31. /* standard_curs[15][0] = 0xfc3f;    1111110000111111 */
  32. /* standard cursor shape : cursor mask array */
  33. /* standard_curs[ 0][1] = 0x0000;    0000000000000000 */
  34. /* standard_curs[ 1][1] = 0x4000;    0100000000000000 */
  35. /* standard_curs[ 2][1] = 0x6000;    0110000000000000 */
  36. /* standard_curs[ 3][1] = 0x7000;    0111000000000000 */
  37. /* standard_curs[ 4][1] = 0x7800;    0111100000000000 */
  38. /* standard_curs[ 5][1] = 0x7c00;    0111110000000000 */
  39. /* standard_curs[ 6][1] = 0x7e00;    0111111000000000 */
  40. /* standard_curs[ 7][1] = 0x7f00;    0111111100000000 */
  41. /* standard_curs[ 8][1] = 0x7f80;    0111111110000000 */
  42. /* standard_curs[ 9][1] = 0x78c0;    0111111111000000 */
  43. /* standard_curs[10][1] = 0x7c00;    0111110000000000 */
  44. /* standard_curs[11][1] = 0x4600;    0000011000000000 */
  45. /* standard_curs[12][1] = 0x0600;    0000011000000000 */
  46. /* standard_curs[13][1] = 0x0300;    0000001100000000 */
  47. /* standard_curs[14][1] = 0x0300;    0000001100000000 */
  48. /* standard_curs[15][1] = 0x0180;    0000000110000000 */
  49. /* up arrow cursor shape : screen mask array */
  50. /* up_arrow_curs[ 0][0] = 0xf9ff;    1111100111111111 */
  51. /* up_arrow_curs[ 1][0] = 0xf0ff;    1111000011111111 */
  52. /* up_arrow_curs[ 2][0] = 0xe07f;    1110000001111111 */
  53. /* up_arrow_curs[ 3][0] = 0xe07f;    1110000001111111 */
  54. /* up_arrow_curs[ 4][0] = 0xc03f;    1100000000111111 */
  55. /* up_arrow_curs[ 5][0] = 0xc03f;    1100000000111111 */
  56. /* up_arrow_curs[ 6][0] = 0x801f;    1000000000011111 */
  57. /* up_arrow_curs[ 7][0] = 0x801f;    1000000000011111 */
  58. /* up_arrow_curs[ 8][0] = 0x000f;    0000000000001111 */
  59. /* up_arrow_curs[ 9][0] = 0x000f;    0000000000001111 */
  60. /* up_arrow_curs[10][0] = 0xf0ff;    1111000011111111 */
  61. /* up_arrow_curs[11][0] = 0xf0ff;    1111000011111111 */
  62. /* up_arrow_curs[12][0] = 0xf0ff;    1111000011111111 */
  63. /* up_arrow_curs[13][0] = 0xf0ff;    1111000011111111 */
  64. /* up_arrow_curs[14][0] = 0xf0ff;    1111000011111111 */
  65. /* up_arrow_curs[15][0] = 0xf0ff;    1111000011111111 */
  66. /* up arrow cursor shape : cursor mask array */
  67. /* up_arrow_curs[ 0][1] = 0x0000;    0000000000000000 */
  68. /* up_arrow_curs[ 1][1] = 0x0600;    0000011000000000 */
  69. /* up_arrow_curs[ 2][1] = 0x0f00;    0000111100000000 */
  70. /* up_arrow_curs[ 3][1] = 0x0f00;    0000111100000000 */
  71. /* up_arrow_curs[ 4][1] = 0x1f80;    0001111110000000 */
  72. /* up_arrow_curs[ 5][1] = 0x1f80;    0001111110000000 */
  73. /* up_arrow_curs[ 6][1] = 0x3fc0;    0011111111000000 */
  74. /* up_arrow_curs[ 7][1] = 0x3fc0;    0011111111000000 */
  75. /* up_arrow_curs[ 8][1] = 0x7fe0;    0111111111100000 */
  76. /* up_arrow_curs[ 9][1] = 0x0600;    0000011000000000 */
  77. /* up_arrow_curs[10][1] = 0x0600;    0000011000000000 */
  78. /* up_arrow_curs[11][1] = 0x0600;    0000011000000000 */
  79. /* up_arrow_curs[12][1] = 0x0600;    0000011000000000 */
  80. /* up_arrow_curs[13][1] = 0x0600;    0000011000000000 */
  81. /* up_arrow_curs[14][1] = 0x0600;    0000011000000000 */
  82. /* up_arrow_curs[15][1] = 0x0000;    0000000000000000 */
  83.  
  84. /* mouse cursor : horizontal and vertical hot spots are defined */
  85. #define standard_horiz_hot_spot -1
  86. #define standard_vert_hot_spot -1
  87. #define up_arrow_horiz_hot_spot -1
  88. #define up_arrow_vert_hot_spot -1
  89.  
  90. /* <<<< Global variables >>>> */
  91. int mouse_text_x;        /* X posn of mouse in Turbo C text coordinates */
  92. int mouse_text_y;        /* Y posn of mouse in Turbo C text coordinates */
  93. int mouse_grph_x;        /* X posn of mouse in graphics coordinates         */
  94. int mouse_grph_y;        /* Y posn of mouse in graphics coordinates         */
  95. int mouse_initialized = 0; /* Set to 1 if mouse_init() succeeds        */
  96.  
  97. /* <<<< Internal variables >>>>    */
  98. /* Previous cursor state.                                */
  99. /* 0 = mouse previously off, 1 means prev on.    */
  100. static int prev_cursor_state = 0;
  101.  
  102. /* Pointer to start of bios video data */
  103. static char far *bios_video_area = (char far *)0x00400049L;
  104.  
  105. /* This variable i for graphics mode only.        */
  106. /* low_resolution = 1 if using 320x200 graphics    */
  107. static int low_resolution = 0;    /* Leave at 0 for text mode        */
  108. static void set_mouse_posn(int *x, int *y);    /* internal function    */
  109. static int low_res_mode(int gd, int gm);        /* internal function */
  110. void mouse(int *m1, int *m2, int *m3, int *m4)
  111.  
  112. /*
  113.     C to mouse driver interface via interrupt 0x33.
  114.     Only supports functions 0-10.
  115.     See your mouse technical reference manual for the
  116.     interface to other functions
  117. */
  118. {
  119.     union REGS inregs, outregs;
  120.     inregs.x.ax = *m1;
  121.     inregs.x.bx = *m2;
  122.     inregs.x.cx = *m3;
  123.     inregs.x.dx = *m4;
  124.     int86(0x33,&inregs,&outregs);
  125.     *m1 = outregs.x.ax;
  126.     *m2 = outregs.x.bx;
  127.     *m3 = outregs.x.cx;
  128.     *m4 = outregs.x.dx;
  129. }
  130.  
  131. int check_mouse_driver(int need_mouse)
  132. /*
  133.     * If need_mouse = 1, then abort program if no mouse.
  134.     * Otherwise, if no mouse return 0, else return 1.
  135. */
  136. {
  137.     void far *address;
  138.     /* get mouse interrupt vector address */
  139.     address = getvect(0x33);
  140.     /* look for NULL address or IRET instruction */
  141.     if ((address == NULL) || (*(unsigned char *)address == 0xcf))
  142.     {
  143.         if (need_mouse)
  144.         {
  145.             printf("Mouse driver NOT installed\n");
  146.             exit(1);
  147.         }
  148.         else return 0;
  149.     }
  150.     return 1;
  151. }
  152.  
  153. int init_mouse(int need_mouse, int gd, int gm)
  154. /*
  155.     Initializes the mouse.  If it can't, and need_mouse = 1,
  156.     this routine exits the program.  Else, it returns
  157.     mouse_initialized = 1.
  158.     If using the mouse for graphics, there are two special cases:
  159.         (1)    If using Hercules graphics, we must let the mouse
  160.                 driver know we're really in graphics mode, cause it
  161.                 can't tell.
  162.         (2)    If using any graphics mode with 320 pixels horizontally,
  163.                 (ie. low resolution),  we must make sure that the mouse
  164.                 coordinates are scaled properly.
  165.     These cases are detected by the parameters gd (graphics driver),
  166.     and parameters gm (graphics mode), as defined by Turbo C graphics.
  167.     If you're just using text mode, set both to zero.
  168.     When fixing up Hercules graphics, we're assuming page 0,  If using
  169.     page 1, set *bios_video_area = 5.
  170. */
  171. {
  172.     int m1;
  173.     mouse_initialized = 0;
  174.     if (check_mouse_driver(need_mouse))
  175.     {
  176.         if (gd == 7) *bios_video_area = 6;    /* Fix up Hercules mode            */
  177.         if (low_res_mode(gd,gm))
  178.             low_resolution = 1;                /* Fix up low resolution mode        */
  179.         m1 = mouse_reset();                    /* Start mouse at ground zero        */
  180.         if (m1)
  181.         {
  182.             mouse_initialized = 1;            /* Set mouse init flag                */
  183.             move_mouse(0,0);                    /* Set coords to top of screen    */
  184.             mouse_on(0);                        /* Turn mouse on for first time    */
  185.         }
  186.         else
  187.         {
  188.             if (need_mouse)
  189.             {
  190.                 printf("ERROR activating mouse ... |n");
  191.                 exit(1);
  192.             }
  193.         }
  194.     }
  195.     return mouse_initialized;
  196. }
  197.  
  198. static int low_res_mode(int gd, int gm)
  199. /* Returns 1 if in any graphics mode with 320 pixels horizontally
  200.     Returns 0 otherwise
  201. */
  202. {
  203.     if (
  204.             (gd == 1 || gd == 2 || gd == 8) &&    /* CGA, MCGA, ATT400 */
  205.             (gm >= 0 && gm <= 3)                /* 320 hz mode */
  206.         )
  207.         return 1;
  208.     return 0;
  209. }
  210.  
  211. int mouse_reset(void)
  212. /* If the mouse was on, it turns it off.
  213.     Then, the mouse state is reset.
  214. */
  215. {
  216.     int x1, m1, m2, m3, m4;
  217.     mouse_off(1);        /* Turn off only if it was on */
  218.     m1 = M_RESET;
  219.     mouse(&m1, &m2, &m3, &m4);
  220.     set_mouse_posn(&m3, &m4);        /* Initialize coordinates */
  221.     return m1;
  222. }
  223.  
  224. void move_mouse(int x, int y)
  225. /* Move mouse cursor to text position (x,y) */
  226. {
  227.     int m1, m2, m3, m4;
  228.     if (!mouse_initialized) return;
  229.     m1 = M_SET_CURS;
  230.     m3 = x*8; m4 = y*8;        /* convert to pixel coordinates */
  231.     mouse(&m1, &m2, &m3, &m4);
  232.     set_mouse_posn(&m3, &m4);
  233. }
  234.  
  235. void mouse_on(int restoreflag)
  236. /* restoreflag = 0 means you want the mouse on regardless of previous state.
  237.     restoreflag = 1 means you want the mouse on only if it was on previously.
  238. */
  239. {
  240.     int m1, m2, m3, m4;
  241.     if (mouse_initialized)
  242.     {
  243.         if (!restoreflag || prev_cursor_state)
  244.         {
  245.             m1 = M_SHOW_CURS;
  246.             mouse(&m1, &m2, &m3, &m4);
  247.             prev_cursor_state = 1;
  248.         }
  249.     }
  250. }
  251.  
  252. void mouse_off(int tempflag)
  253. /* If tempflag = 1, it means you want to turn the mouse off, and if
  254.     it had been on set previous state to on.
  255.     If tempflag = 0, it means you want to turn mouse off, and regardless
  256.     off whether it was on or not, set previous state to off.
  257. */
  258. {
  259.     int m1, m2, m3, m4;
  260.     if (mouse_initialized)
  261.     {
  262.         if (prev_cursor_state)        /* Turn it off only if it was on    */
  263.         {
  264.             m1 = M_HIDE_CURS;
  265.             mouse(&m1, &m2, &m3, &m4);
  266.             /* leave prev_cursor_state alone if just turning off temporarily */
  267.             if (!tempflag) prev_cursor_state = 0;
  268.         }
  269.     }
  270. }
  271.  
  272. void mouse_grph_posn(int *x, int *y)
  273. /* Returns the mouse graphics coordinates if the mouse is
  274.     initialized, else it returns (0,0).
  275. */
  276. {
  277.     int m1, m2;
  278.     if (mouse_initialized)
  279.     {
  280.         m1 = M_GET_STATUS;
  281.         mouse(&m1, &m2, x, y);
  282.         set_mouse_posn(x, y);
  283.     }
  284.     else {
  285.         *x = 0; *y = 0;    /* default to left corner */
  286.     }
  287.     return;
  288. }
  289.  
  290. void mouse_txt_posn(int *x, int *y)
  291. /* Returns the mouse text coordinates if the mouse is
  292.     initialized, else it returns (1,1).
  293. */
  294. {
  295.     mouse_grph_posn(x,y);
  296.     *x = mouse_text_x;
  297.     *y = mouse_text_y;
  298.     return;
  299. }
  300.  
  301. int mouse_in_box(int graphflag, int left, int top, int right, int bottom)
  302. /* Returns 1 if the mouse is in the box given by the
  303.     coordinates, 0 otherwise.  The type of coordinates is
  304.     given by graphflag.  If graphflag = 1, the coordinates
  305.     are assumed to be graphics coordinates, else they're
  306.     text coordinates.  Either way they are absolute coordinates.
  307.     In order for this routine to work porperly you must first
  308.     call mouse_txt_posn, mouse_grph_posn, or any of the
  309.     mouse funcitons that set the global mouse position variables.
  310.     If mouse not initialized, it returns 0;
  311. */
  312. {
  313.     int x, y;
  314.     if (mouse_initialized)
  315.     {
  316.         if (graphflag)
  317.         {
  318.             x = mouse_grph_x;
  319.             y = mouse_grph_y;
  320.         }
  321.         else
  322.         {
  323.             x = mouse_text_x;
  324.             y = mouse_text_y;
  325.         }
  326.         if ((y >= top) && (y <= bottom) &&
  327.              (x >= left) && (x <= right))    return 1;
  328.     }
  329.     return 0;
  330. }
  331.  
  332. int button_release(int b)
  333. /* Looks for a left (b=0) or right (b=1) mouse button release.
  334.     Returns 1 if the button has been released since the last time
  335.     called, else returns 0.  If no mouse installed, it returns 0.
  336. */
  337. {
  338.     int m1, m2, m3, m4;
  339.     if (mouse_initialized)
  340.     {
  341.         m1 = M_GET_REL;
  342.         m2 = b;    /* which button */
  343.         mouse(&m1, &m2, &m3, &m4);
  344.         set_mouse_posn(&m3, &m4);
  345.         if (m2) return 1;
  346.     }
  347.     return 0;
  348. }
  349.  
  350. int button_press(int b)
  351. /* Looks for a left (b=0) or right (b=1) mouse button press.
  352.     Returns 1 if the button has been released since the last time
  353.     called, else returns 0.  If no mouse installed, it returns 0.
  354. */
  355. {
  356.     int m1, m2, m3, m4;
  357.     if (mouse_initialized)
  358.     {
  359.         m1 = M_GET_PRESS;
  360.         m2 = b;    /* which button */
  361.         mouse(&m1, &m2, &m3, &m4);
  362.         set_mouse_posn(&m3, &m4);
  363.         if (m2) return 1;
  364.     }
  365.     return 0;
  366. }
  367.  
  368. int button_state()
  369. /* Returns up/down state of the mouse buttons.  A button is
  370.     down if its corresponding bit = 1.
  371.         Bit    2    Middle button (Logitech mouse only)
  372.                 1    Right button
  373.         LSB    0    Left button
  374.     Returns 0x00 if no button down or no mouse installed.
  375.     Also stores mouse position information.
  376. */
  377. {
  378.     int m1, m2, m3, m4;
  379.     if (mouse_initialized)
  380.     {
  381.         m1 = M_GET_STATUS;
  382.         mouse(&m1, &m2, &m3, &m4);
  383.         set_mouse_posn(&m3, &m4);
  384.         return m2;
  385.     }
  386.     return 0;
  387. }
  388.  
  389. static void set_mouse_posn(int *x, int *y)
  390. /* Sets the internal mouse position variables
  391.     Corrects for 320x200 low resolution modes
  392. */
  393. {
  394.     if (low_resolution) *x >>= 1;        /* divide by two    */
  395.     mouse_grph_x = *x;
  396.     mouse_grph_y = *y;
  397.     mouse_text_x = *x/8 + 1;
  398.     mouse_text_y = *y/8 + 1;
  399. }
  400.  
  401. int mouse_trigger(int button_dir)
  402. /* Looks for a key press, or a button release (if button_dir = 0)
  403.     or press (if button_dir = 1).  Key presses have priority over
  404.     mouse buttons.  The left mouse button has priority over the
  405.     right button.  If a key has been pressed, it is then removed
  406.     from the keyboard buffer.
  407. */
  408. {
  409.     int k;
  410.     if (bioskey(1))
  411.     {
  412.         k = bioskey(0);
  413.     }
  414.     else
  415.     {
  416.         k = 0;
  417.         if (button_dir)
  418.         {
  419.             if (button_press(0)) k = LEFT_MOUSE_PRESS;
  420.             else if (button_press(1)) k = RIGHT_MOUSE_PRESS;
  421.         }
  422.         else
  423.         {
  424.             if (button_release(0)) k = LEFT_MOUSE_REL;
  425.             else if (button_release(1)) k = RIGHT_MOUSE_REL;
  426.         }
  427.     }
  428.     return k;
  429. }
  430.  
  431. void mouse_debounce(void)
  432. /* Debounces mouse buttons by waiting 10 milliseconds. */
  433. {
  434.     int x1, m1, m2, m3, m4;
  435.     delay(10);
  436.     m1 = M_CHANGE_CURS;
  437.     do
  438.     {
  439.         mouse(&m1, &m2, &m3, &m4);
  440.     }
  441.     while (m2 != 0);
  442. }
  443.  
  444. int mouse_cursor(int *cursor, int horiz, int vert)
  445. /* Mouse cursor shapes are set. */
  446. {
  447.     int m1, m2, m3, m4;
  448.     if (mouse_initialized)
  449.     {
  450.        m1 = 9;
  451.         m2 = horiz;        /* horizontal hot spot */
  452.         m3 = vert;        /* vertical hot spot */
  453.         mouse(&m1, &m2, &m3, cursor);
  454.         return 1;
  455.     }
  456.     return 0;
  457. }
  458.  
  459. int set_mouse_xbounds(int left, int right)
  460. /* set x-axis limits for mouse */
  461. {
  462.     int m1, m2, m3, m4;
  463.     if (mouse_initialized)
  464.     {
  465.         m1 = M_SET_X_BOUNDS;
  466.         m3 = left*8 - 1; m4 = right*8 - 1; /* convert to pixel coordinates */
  467.         mouse(&m1, &m2, &m3, &m4);
  468.         set_mouse_posn(&m3, &m4);
  469.     }
  470. }
  471.  
  472. int set_mouse_ybounds(int top, int bottom)
  473. /* set y-axis limits for mouse */
  474. {
  475.     int m1, m2, m3, m4;
  476.     if (mouse_initialized)
  477.     {
  478.         m1 = M_SET_Y_BOUNDS;
  479.         m3 = top*8 - 1; m4 = bottom*8 - 1; /* convert to pixel coordinates */
  480.         mouse(&m1, &m2, &m3, &m4);
  481.         set_mouse_posn(&m3, &m4);
  482.     }
  483. }
  484.  
  485. int set_mouse_window(int left, int top, int right, int bottom)
  486. /* set x-axis and y-axis window for mouse.  If left and/or
  487.     are CTRWIN it means that window should be centered on the screen
  488.     and that right and/or bottom are entire window size */
  489. {
  490.     if (mouse_initialized)
  491.     {
  492.         if (left == CTRWIN) {    /* means that right = width of entire window */
  493.             left = ((80-right)/2);    /* corrected left value */
  494.             right = left + right - 1;    /* corrected right value */
  495.         }
  496.         if (top == CTRWIN) {        /* means that bottom = height of entire window */
  497.             top = ((25-bottom)/2);
  498.             bottom = top + bottom - 1;
  499.         }
  500.         set_mouse_xbounds(left,right);
  501.         set_mouse_ybounds(top,bottom);
  502.     }
  503. }